Previous Book Contents Book Index Next

Inside Macintosh: QuickDraw GX Objects /
Chapter 2 - Shape Objects / Using Shape Objects


Creating and Manipulating Shape Objects

This section describes how you can create and interact with shape objects as whole entities--to create, dispose of, copy, compare, clone, cache, load, and unload them. It
also describes how to manipulate the default shapes. Manipulating the properties of shapes is described under "Manipulating Shape Object Properties" beginning on page 2-28.

Getting and Setting the Default Shape Objects

QuickDraw GX defines a default shape object for each shape type. These defaults are the templates QuickDraw GX uses when creating new shape objects, and you can change them to suit your purposes. Note, however, that changing the geometry for a default shape has no effect when subsequent shapes are created from the default one. A newly created shape never contains a geometry.

You can use the GXGetDefaultShape function to examine one of the default shape objects and the GXSetDefaultShape function to replace one of the default shape objects.

The properties common to all default shape objects are described under "Default Shapes" on page 2-18. Default properties specific to graphic or typographic shapes are described in Inside Macintosh: QuickDraw GX Graphics and Inside Macintosh: QuickDraw GX Typography, respectively.

The following code fragment uses GXGetDefaultShape to change the characteristics of the ink object referenced by the default line shape. The code obtains a reference to the default shape, and creates a temporary ink reference (tempInk) to the shape's ink object. It changes the temporary ink's color and transfer mode (with library functions SetInkCommonColor and SetInkCommonTransfer), and then assigns the modified ink back to the default shape:

tempInk = GXCopyToInk(nil,GXGetShapeInk
                     (GXGetDefaultShape(gxLineType)));
SetInkCommonColor(tempInk, gxBlack);
SetInkCommonTransfer(tempInk, gxXorMode);
GXSetShapeInk(GXGetDefaultShape(gxLineType),tempInk);
GXDisposeInk(tempInk);
The code disposes of the temporary ink after assigning it to the default shape, because that temporary reference is no longer needed.

Note
If you have created a shape object, and want to restore some of its default values, you can use the GXResetShape function. See the section "Resetting a Shape Object's Properties to Their Default Values" beginning on page 2-31.
The GXGetDefaultShape function is described on page 2-52. The GXSetDefaultShape function is described on page 2-53.

Creating and Disposing of Shape Objects

QuickDraw GX provides a number of ways for you to create a new shape object. This section describes the GXNewShape function, which creates a copy of the default shape for the shape type you specify. You can then customize the shape using the techniques described in the section "Manipulating Shape Object Properties" beginning on page 2-28. Other ways to create and customize specific types of shape objects are described in the chapters that describe shapes in Inside Macintosh: QuickDraw GX Graphics and Inside Macintosh: QuickDraw GX Typography. Note that you can also create a new shape by copying an existing one: see the section "Copying, Comparing, and Cloning Shape Objects" beginning on page 2-25.

Before you can create a shape or any other object, you need to be in the QuickDraw GX environment. You are not required to make any calls to accomplish this, however; QuickDraw GX sets up the environment for your application when you make your
first QuickDraw GX call. If you nevertheless wish to control your application's
memory use in the QuickDraw GX environment, you can use the functions GXNewGraphicsClient and GXEnterGraphics, described in the memory management chapter of Inside Macintosh: QuickDraw GX Environment and Utilities.

The following code fragment creates a rectangle shape (rectShape), assigns it a fill type (closed-frame fill), and assigns its ink object a gray color (using the library function SetShapeCommonColor):

rectShape = GXNewShape (gxRectangleType);
GXSetShapeFill (rectShape, gxClosedFrameFill);
SetShapeCommonColor (rectShape, gxGray);
The following code fragment creates a picture shape (docPage) to represent the page of a document that is to be printed. It sets the gxUniqueItemsShape shape attribute to make sure each item in the picture has a unique reference:

docPage = GXNewShape(gxPictureType);
GXSetShapeAttributes(docPage, gxUniqueItemsShape);
(Note that this method of assigning an attribute clears all other attributes, which may be undesirable. In general, you would first call GXGetShapeAttributes, modify the returned attributes as needed, and then call GXSetShapeAttributes to reassign them.)

To delete your application's reference to a shape object, call the GXDisposeShape function. You must be sure to dispose of every shape that you create. For the docPage shape you would make this call:

GXDisposeShape(docPage);
Note that calling GXDisposeShape for a particular shape object may or may not actually release the memory allocated for that object, depending on its owner count. GXDisposeShape decreases the shape object's owner count by 1; if that brings the owner count to 0, the shape is completely deleted and its memory released (and the owner count of each object that the shape object references is then decremented).
See "Manipulating a Shape Object's Owner Count" on page 2-31.

The GXNewShape function is described on page 2-54. The GXDisposeShape function
is described on page 2-55.

Getting the Size of a Shape Object in Memory

Although the sizes of style, ink, and transform objects are relatively constant, shape objects vary greatly in size, mostly due to the differences in their geometries. The GXGetShapeSize function allows you to find out how much memory a shape occupies.

The GXGetShapeSize function returns only the amount of memory currently being used to represent the shape. Because QuickDraw GX can automatically unload objects from memory, the size returned by GXGetShapeSize does not accurately reflect the size of the object if it has been unloaded. You can call the GXLoadShape function before calling GXGetShapeSize to get a more accurate size, if necessary.

The GXGetShapeSize function is described on page 2-56.

Copying, Comparing, and Cloning Shape Objects

You can use the GXCopyToShape and GXCopyDeepToShape functions to copy all of the information from one shape to another or to create a new copy of a shape. The two functions are identical except that GXCopyDeepToShape copies more information for these shape types: for bitmap shapes, it also copies the pixel image; for picture shapes, it makes a new copy of each shape in the picture; and for glyph and layout shapes, it copies the style list.

The following code fragment copies a shape to make a version having special visual characteristics. It makes a temporary shape (tempTextShape) that is a copy of a text shape (textShapeFromPicture) within a picture shape representing a document page. The GXCopyDeepToShape function is not needed in this case because a text shape, unlike a glyph shape or layout shape, cannot have a style list to copy. The code doubles the size of the text and moves it by 100 points vertically before inserting it back into the page and disposing of the temporary reference.

Note that this code makes use of the QuickDraw GX ff macro, a shorthand version of the IntToFixed macro. Both functions are described in the mathematics chapter of Inside Macintosh: QuickDraw GX Environment and Utilities.

GXGetPictureParts(thePage, 2, 1, &textShapeFromPicture, 
                  nil, nil, nil);
tempTextShape = GXCopyToShape (nil, textShapeFromPicture);

GXScaleShape(tempTextShape, ff(2), ff(2), 0, 0);
GXMoveShape(tempTextShape, 0, ff(100));

GXSetPictureParts(thePage, 3, 0, 1, &tempTextShape, 
                  nil, nil, nil);
GXDisposeShape(tempTextShape);
You can test if two shape references refer to the same shape object by simply testing the references for equality. You can also compare two different shape objects for equality with the GXEqualShape function. For two shapes to be equal, their fill properties must be equal and their geometries must be identical. See the GXEqualInk, GXEqualStyle, and GXEqualTransform function descriptions in the chapters "Ink Objects," "Style Objects," and "Transform Objects," respectively, in this book for the requirements for equality. Shape copies created by GXCopyToShape or GXCopyDeepToShape are always equal to the shape from which they were copied.

Equivalent geometries are not identical
Some shapes have equivalent, but not identical, geometries, and are thus not considered equal by GXEqualShape. For example, two polygons might have identical geometries, except that one has a duplicate point at one of its corners. The shapes are equivalent in form, but their geometries are not identical.You can remove such duplicate points with the GXReduceShape function, described in the geometric operations chapter of Inside Macintosh: QuickDraw GX Graphics.
In certain circumstances, you may want to copy a reference to a shape object without actually copying the shape object. For example, you may want two variables to refer to the same shape object, so that editing one of them affects both. This is called cloning a shape, rather than copying a shape. You can use the GXCloneShape function to clone a shape object.

Functionally, GXCloneShape does nothing more than increase the owner count of a shape object. For more information about cloning objects, see the chapter "Introduction to Objects" in this book. For information on manipulating shape owner counts, see the section "Manipulating a Shape Object's Owner Count" beginning on page 2-31 of this chapter.

The GXCopyToShape function is described on page 2-57. The GXCopyDeepToShape function is described on page 2-58. The GXEqualShape function is described on page 2-60. The GXCloneShape function is described on page 2-61.

Caching Shape Objects

Before QuickDraw GX draws any shape, it first performs some preliminary calculations on the shape's data (such as finding the shape's bounds) and stores the information in a shape cache.

In certain circumstances, you can improve the way drawing occurs on the screen by requesting that QuickDraw GX create the caches before you actually draw the shapes. For example, if you are drawing many shapes at once, you can cache all of the shapes before you draw any of them. In this way, you can minimize the amount of time between the appearance of the first shape and the completion of the last shape.

You can use the GXCacheShape function to create caches before drawing and you can use the GXDisposeShapeCache function to release the memory held by a shape cache. The GXGetShapeCacheSize function returns information about the size of the cache in memory.

The GXCacheShape function works somewhat differently from the gxCachedShape attribute (see Table 2-4 on page 2-16). Setting the gxCachedShape attribute causes QuickDraw GX to cache and predraw a shape into a compressed offscreen bitmap the first time it is drawn. Then, when you call GXDrawShape, the predrawn shape is simply transferred to the screen. Setting the gxCachedShape attribute causes very fast drawing but may greatly increase the memory required to store a shape, especially for large shapes. Calling GXCacheShape does not increase the memory required to draw a shape. For the fastest possible drawing (but the slowest preparation for drawing), set the gxCachedShape attribute and also call GXCacheShape before drawing.

You are not required to use any of the functions in this section. QuickDraw GX automatically creates shape caches when you draw a shape and automatically deletes shape caches when memory is low. You only need to use these functions when you want to improve your application's drawing speed.

The GXCacheShape function is described on page 2-62; The GXDisposeShapeCache function is described on page 2-63; The GXGetShapeCacheSize function is described on page 2-64.

Loading and Unloading Shape Objects

Although you rarely need to, you can influence memory-allocation decisions involving objects that you have created. If your application needs to have a shape object in memory, it can force QuickDraw GX to load it into memory. When your application
no longer needs the shape object in a loaded state, it can instruct QuickDraw GX to unload it.

You call the GXLoadShape function to make sure that a shape object is in memory; if necessary, QuickDraw GX brings the object into memory from an unloaded state. You can call the GXUnloadShape function to instruct QuickDraw GX that it is free to unload the shape object at any time.

Rather than explicitly instructing QuickDraw GX to load or unload an object, you can also set either the gxDiskShape or the gxMemoryShape attribute for the shape, which permanently affects the priority with which QuickDraw GX loads or unloads the shape. Shape attributes are described in Table 2-4 on page 2-16.

The GXLoadShape and GXUnloadshape functions are described in the memory management chapter of Inside Macintosh: QuickDraw GX Environment and Utilities.


Previous Book Contents Book Index Next

© Apple Computer, Inc.
7 JUL 1996